using System;
using System.Collections.Generic;
using System.IO;

namespace DaphneTranslator.BusinessLogic
{
	public enum enumFormatType { Xml };
	
	/// <summary>
	/// Language manager - main class for saving and loading language texts.
	/// </summary>
	public class LanguageManager
	{
		public LanguageManager ()
		{
		}
		
		/// <summary>
		/// The main load method
		/// </summary>
		public CultureCollection Load (string sDirPath, enumFormatType eFormatType)
		{
			ILoader loader = GetLoader (eFormatType);
			
			// generate list of files
			List<string> lstSearchPatterns = GetSearchPatterns (eFormatType);
			FileFinder ff = new FileFinder ();						
			List<string> lstFiles = ff.EnumerateFiles (sDirPath, lstSearchPatterns);
			
			CultureCollection list = new CultureCollection ();
			list.MapperEngine = GetMapper (eFormatType);
			
			
			foreach (string sFile in lstFiles) {
				try {
					// fill in language file
					LanguageFile lngFile = loader.Load (sFile);
					lngFile.OriginalFilePath = sFile;
					lngFile.Filename = Path.GetFileName (sFile);
					string sDirectory = Path.GetDirectoryName (sFile);
					lngFile.RelativePath = DirectoryHelper.RelativePath (sDirectory, sDirPath); 
					
					
					// find language list
					CultureRecord lngList = null;
					foreach (var item in list.CultureList) {
						if (item.Culture == lngFile.Culture) {
							lngList = item;
							break;
						}						
					}
					// check if exists;
					if (lngList == null) {
						lngList = new CultureRecord ();
						lngList.Culture = lngFile.Culture;
						lngList.CultureName = lngFile.CultureName;
						lngList.EnglishName = lngFile.EnglishName;
						list.CultureList.Add (lngList);
					}
					// finally add file
					lngList.Files.Add (lngFile);
					
					string sRelativePath = Path.Combine (lngFile.RelativePath, lngFile.Filename);					
					list.MapperEngine.ResolveFile (list.FileMapperContainer, sRelativePath);
				} catch {
				}							
			}
			
			return list;										
		}
		
		/// <summary>
		/// The main save method
		/// </summary>
		public void Save (CultureCollection lstLanguages, enumFormatType eFormatType, string sSaveDir)
		{
			ISaver saver = GetSaver (eFormatType);
			
			foreach (CultureRecord lang in lstLanguages.CultureList) {
				foreach (LanguageFile lngFile in lang.Files) {
					string sDirectory = Path.Combine (sSaveDir, lngFile.RelativePath);
					if (Directory.Exists (sDirectory) == false)
						Directory.CreateDirectory (sDirectory);
					string sSaveFilePath = Path.Combine (sDirectory, lngFile.Filename);
					saver.Save(sSaveFilePath, lngFile);
				}
			}		
		}
						
		private List<string> GetSearchPatterns (enumFormatType eFormatType)
		{
			List<string> lstPatterns = new List<string> ();
			
			switch (eFormatType) {
			case enumFormatType.Xml:
				lstPatterns.Add ("*.xml");
				break;
			default:
				throw new ApplicationException ("Unknown format type");
			}										
			
			return lstPatterns;
		}
			
		private ILoader GetLoader (enumFormatType eFormatType)
		{
			switch (eFormatType) {
			case enumFormatType.Xml:
				return new XmlLoader ();
			default:
				throw new ApplicationException("Unknown format type");
					
			}
		}
		
		private ISaver GetSaver (enumFormatType eFormatType)
		{
			switch (eFormatType) {
			case enumFormatType.Xml:
				return new XmlSaver ();
			default:
				throw new ApplicationException ("Unknown format type");			
			}
		}
		
		private IMapper GetMapper (enumFormatType eFormatType)
		{
			switch (eFormatType) {
			case enumFormatType.Xml:
				return new XmlFileMapper ();
			default:
				throw new ApplicationException ("Unknown format type");							
			}						
		}
	}
}

